/******************************************************************************

	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2010.

	This file is part of Maxsi Engine.

	Maxsi Engine is free software: you can redistribute it and/or modify it
	under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or (at your
	option) any later version.

	Maxsi engine is distributed in the hope that it will be useful, but WITHOUT
	ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
	FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
	for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with Maxsi Engine. If not, see <http://www.gnu.org/licenses/>.

	MaxsiEngine.dll
	A general purpose C++ library for the Maxsi Technology Project.

	MaxsiWindowSystem.h
	A powerful UI System abstraction layer that allows the same UI code to run
	on any platform that implements a Maxsi Window System.

******************************************************************************/

#ifndef MaxsiWindowSystem_H
#define MaxsiWindowSystem_H

BeginMaxsiNamespace

//=============================================================================
//	Defines.
//=============================================================================
#define Maxsi_Window_CenterX INT_MIN
#define Maxsi_Window_CenterY INT_MIN

//=============================================================================
//	Hacks to avoid naming collisions on Windows. Ew.
//=============================================================================
#ifdef CreateWindow
#undef CreateWindow
#endif

//=============================================================================
//	Forward declarations.
//=============================================================================
class MaxsiControlSystem;
class MaxsiWindow;
class MaxsiWindowSystem;

//=============================================================================
//	Define where the MaxsiWindowSystem interface is declared.
//=============================================================================
#undef MAXSI_INTERFACE
#define MAXSI_INTERFACE MAXSI_INTERFACE_ABSTRACT_BASECLASS

//=============================================================================
//	MaxsiWindowSystem - A layer that allows us to use the MaxsiWindow class for
//	all high-level UI stuff, while this class' children works with the GTK API
//	or Windows API, or whatever API we want to use. To switch platform we just
//	have to recreate the MaxsiWindow on another MaxsiWindowSystem.
//=============================================================================
CLASSLINK MaxsiWindowSystem
{
public:
	MaxsiWindowSystem();
	~MaxsiWindowSystem();

public:
	MaxsiControlSystem* ControlSystem;

public:
	//=============================================================================
	//	Copy-pasteable interface starts here:
	//=============================================================================

	//=============================================================================
	//	MaxsiControlSystem* GetControlSystem();
	//
	//	Returns a pointer to a class that can create and handle controls on this
	//	kind of Maxsi Window System.
	//=============================================================================
	virtual MaxsiControlSystem* GetControlSystem() MAXSI_INTERFACE;
	
	//=============================================================================
	//	MaxsiControlSystem* CreateControlSystem();
	//
	//	Allocates a new instance of the control system for this window system.
	//=============================================================================
	virtual MaxsiControlSystem* CreateControlSystem() MAXSI_INTERFACE;
	
	//=============================================================================
	//	bool DeleteControlSystem(MaxsiControlSystem* ControlSystem);
	//
	//	Deallocates an instance of the control system for this window system.
	//=============================================================================
	virtual bool DeleteControlSystem(MaxsiControlSystem* ControlSystem) MAXSI_INTERFACE;

	//=============================================================================
	//	int Initialize(int* argc, int** argv);
	//	
	//	Initializes this Window System if it hasn't already been initialized. From
	//	this point on it is perfectly safe to use this Window System to create
	//	MaxsiWindows with. This function is allowed to change argc and argv.
	//=============================================================================
	virtual int Initialize(int* argc, char*** argv) MAXSI_INTERFACE;

	//=============================================================================
	//	int MainLoop();
	//
	//	Runs the mainloop code for this kind of Window System.
	//=============================================================================
	virtual int MainLoop() MAXSI_INTERFACE;

	//=============================================================================
	//	MaxsiHandle CreateWindow(MaxsiHandle Parent, int Width, int Height,
	//	int Left, int Top, MESTR* Title);
	//
	//	Creates a new window using this window system and returns a handle to the
	//	Window. Returns NULL upon failure.
	//=============================================================================
	virtual MaxsiHandle CreateWindow(MaxsiHandle Parent, int Width, int Height, int Left, int Top, MESTR* Title) MAXSI_INTERFACE;

	//=============================================================================
	//	bool ShowWindow(MaxsiHandle Window);
	//
	//	Changes the visibillity of the Window pointed to by the handle.
	//=============================================================================
	virtual bool ShowWindow(MaxsiHandle Window) MAXSI_INTERFACE;

	//=============================================================================
	//	bool HideWindow(MaxsiHandle Window);
	//
	//	Changes the visibillity of the Window pointed to by the handle.
	//=============================================================================
	virtual bool HideWindow(MaxsiHandle Window) MAXSI_INTERFACE;

	//============================================================================
	//	MaxsiHandle CreatePictureBufferFromFile(MESTR* FileName);
	//
	//	Returns a picture buffer containing the image data found in FileName.
	//	Call DeletePictureBuffer when done with the pictue buffer.
	//============================================================================
	virtual MaxsiHandle CreatePictureBufferFromFile(MESTR* FileName) MAXSI_INTERFACE;

	//============================================================================
	//	bool DeletePictureBuffer(MaxsiHandle PictureBuffer);
	//
	//	Deletes a previously allocatec picture buffer and returns true.
	//============================================================================
	virtual bool DeletePictureBuffer(MaxsiHandle PictureBuffer) MAXSI_INTERFACE;

	//============================================================================
	//	bool DeletePictureBuffer(MaxsiHandle PictureBuffer);
	//
	//	Deletes a picture buffer allocated using CreatePictureBuffer*().
	//============================================================================
	virtual bool SetWindowIcon(MaxsiHandle Window, MaxsiHandle Icon) MAXSI_INTERFACE;

	//=============================================================================
	//	int MoveWindowControl(MaxsiHandle Control, int Top, int Left, int Width, int 
	//	Height, bool UnusedInLinux);
	//
	//	Sets the location and size of a control on this Maxsi Window.
	//=============================================================================
	virtual int MoveWindowControl(MaxsiHandle Parent, MaxsiHandle Control, int Top, int Left, int Width, int Height, bool UnusedInLinux) MAXSI_INTERFACE;

	virtual int MsgBox(MaxsiHandle Parent, int Flags, MESTR* Message, MESTR* Title) MAXSI_INTERFACE;

};

//=============================================================================
//	Define where the MaxsiControlSystem interface is declared.
//=============================================================================
#undef MAXSI_INTERFACE
#define MAXSI_INTERFACE MAXSI_INTERFACE_ABSTRACT_BASECLASS

//=============================================================================
//	MaxsiControlSystem - An interface for creating UI elements using various
//	Maxsi Window Systems.
//=============================================================================
CLASSLINK MaxsiControlSystem
{
public:
	MaxsiWindowSystem*	MyWindowSystem;

public:
	//=============================================================================
	//	MaxsiWindowSystem* WindowSystem();
	//
	//	Returns a pointer to the Window System in use around here.
	//=============================================================================
	virtual MaxsiWindowSystem* WindowSystem();

	//=============================================================================
	//	bool SetWindowSystem(MaxsiWindowSystem* NewWindowSystem);
	//
	//	Sets the Window System in use around here.
	//=============================================================================
	virtual	bool SetWindowSystem(MaxsiWindowSystem* NewWindowSystem);

public:
	//=============================================================================
	//	Copy-pasteable interface starts here:
	//=============================================================================

	//=============================================================================
	//	bool DeleteControl(MaxsiHandle Control);
	//
	//	Deletes a control from its parent and clears memory, whatsoever!
	//=============================================================================
	virtual bool DeleteControl(MaxsiHandle Control) MAXSI_INTERFACE;

	//=============================================================================
	//	MaxsiHandle CreateControlType(MaxsiHandle Parent);
	//	
	//	Creates a control of the type ControlType on the MaxsiWindow* Parent.
	//=============================================================================
	virtual MaxsiHandle CreateFrame(MaxsiHandle Parent) MAXSI_INTERFACE;
	virtual MaxsiHandle CreateLabel(MaxsiHandle Parent) MAXSI_INTERFACE;
	virtual MaxsiHandle CreateButton(MaxsiHandle Parent) MAXSI_INTERFACE;	
	virtual MaxsiHandle CreateTextSingleLine(MaxsiHandle Parent) MAXSI_INTERFACE;
	virtual MaxsiHandle CreateTextMultiLine(MaxsiHandle Parent) MAXSI_INTERFACE;
	virtual MaxsiHandle CreateRadioButton(MaxsiHandle Parent) MAXSI_INTERFACE;
	virtual MaxsiHandle CreateCheckButton(MaxsiHandle Parent) MAXSI_INTERFACE;
	virtual MaxsiHandle CreateProgressBar(MaxsiHandle Parent) MAXSI_INTERFACE;
	virtual MaxsiHandle CreateTreeView(MaxsiHandle Parent) MAXSI_INTERFACE;
	virtual MaxsiHandle CreateListView(MaxsiHandle Parent) MAXSI_INTERFACE;
	virtual MaxsiHandle CreateSeparatorH(MaxsiHandle Parent) MAXSI_INTERFACE;

	virtual bool SetLabelText(MaxsiHandle Control, MESTR* Text) MAXSI_INTERFACE;
	virtual bool SetButtonText(MaxsiHandle Control, MESTR* Text) MAXSI_INTERFACE;
	virtual bool SetProgress(MaxsiHandle Control, float Progress) MAXSI_INTERFACE;

};

//=============================================================================
//	Remember to reset MAXSI_INTERFACE when done with it for safety reasons.
//=============================================================================
#undef MAXSI_INTERFACE
#define MAXSI_INTERFACE MAXSI_INTERFACE_RESET_IT_TO_THIS

//=============================================================================
// MaxsiWindow - A window containing UI elements.
//=============================================================================
CLASSLINK MaxsiWindow
{
public:
	MaxsiWindow();
	~MaxsiWindow();

public:
	//=============================================================================
	//	MaxsiWindowSystem* WindowSystem();
	//
	//	Returns a pointer to the Window System in use around here.
	//=============================================================================
	virtual MaxsiWindowSystem* WindowSystem();

	//=============================================================================
	//	MaxsiControlSystem* ControlSystem();
	//
	//	Returns a pointer to the Control System in use around here.
	//=============================================================================
	virtual MaxsiControlSystem* ControlSystem();

public:
	virtual	bool SetWindowSystem(MaxsiWindowSystem* NewWindowSystem);

public:
	//=============================================================================
	//	bool CreateWindow(int WindowWidth = 0, int WindowHeight = 0);
	//
	//	Creates the Window, creates the controls, and initialized stuff. Returns
	//	true on success, false on failure.
	//=============================================================================
	virtual bool CreateWindow(int WindowWidth = 0, int WindowHeight = 0);

	//=============================================================================
	//	bool DeleteWindow();
	//
	//	Closes the Window, removes the controls, clears up any allocated memory. It
	//	is perfectly safe to call CreateWindow() after calling DeleteWindow().
	//=============================================================================
	virtual bool DeleteWindow();

	//=============================================================================
	//	bool UpdateWindow();
	//
	//	Checks for any changed states and updates the window as necessary.
	//=============================================================================
	virtual bool UpdateWindow();

public:
	//=============================================================================
	//	bool CreateControls();
	//
	//	Creates the controls. Returns true on success, false if the controls could
	//	not be created.
	//=============================================================================
	virtual bool CreateControls();

	//=============================================================================
	//	bool DeleteControls();
	//
	//	Deletes the controls on the Window.
	//=============================================================================
	virtual bool DeleteControls();

	//=============================================================================
	//	bool UpdateControls();
	//
	//	Checks for any changed states, such as a window resize, and updates the
	//	Window controls as necessary.
	//=============================================================================
	virtual bool UpdateControls();

public:
	//=============================================================================
	//	int MoveWindow(MaxsiHandle Control, int Top, int Left, int Width, int 
	//	Height, bool UnusedInLinux);
	//
	//	Sets the location and size of a control on this Maxsi Window.
	//=============================================================================
	virtual int MoveWindow(MaxsiHandle Control, int Top, int Left, int Width, int Height, bool UnusedInLinux);

public:
	virtual MESTR* GetWindowTitle();
	virtual int GetDefaultWidth();
	virtual int GetDefaultHeight();
	virtual	bool UpdateWindowIcon();

public:
	//=============================================================================
	//	State variables.
	//=============================================================================
	int	Width;
	int	Height;

public:
	//=============================================================================
	//	Widgets Handles.
	//=============================================================================
	MaxsiHandle	Window;
	MaxsiHandle	Frame;

private:
	MaxsiWindowSystem*	MyWindowSystem; // Please call WindowSystem() instead.
	
};

//=============================================================================
//	MaxsiWindowSystem* CreateLocalWindowSystem();
//
//	Creates a new instance of the preferred Maxsi Window System for this
//	platform. This must be deleted using DeleteLocalWindowSystem() when you are
//	done with it.
//=============================================================================
LINK MaxsiWindowSystem* CreateLocalWindowSystem();

//=============================================================================
//	bool DeleteLocalWindowSystem(MaxsiWindowSystem* WindowSystem);
//
//	Deletes a Maxsi Window System returned by CreateLocalWindowSystem().
//=============================================================================
LINK bool DeleteLocalWindowSystem(MaxsiWindowSystem* WindowSystem);

//=============================================================================
//	int CriticalMsgBox(MaxsiHandle Parent, int Flags, MESTR* ErrorTitle, MESTR*
//	ErrorMessage);
//
//	Displays a message box to the end user, if possible. You should only use
//	this function in cases things go very, very wrong. Otherwise, consider
//	using the MsgBox function of your local Maxsi Window System. This function
//	is provided in case your local Maxsi Window System encountered a critical
//	error and cannot handle this error message it self. In such a case, this
//	function might fail too, but you never know. Returns non-zero if the
//	message box was successfully displayed.
//=============================================================================
LINK int CriticalMsgBox(MaxsiHandle Parent, int Flags, MESTR* ErrorMessage, MESTR* ErrorTitle);

EndMaxsiNamespace

#endif
